#!/usr/local/bin/perl
use strict;
use Data::Dumper;

my $TESTENV = 0;

my %jobrev;

my $branch = $ARGV[0];
exit if ($branch eq '');
my $g_todo_dir  = "/volume/dc-build01-d/QDIR/jobs-todo/$branch";
my $g_doing_dir = "/volume/dc-build01-d/QDIR/jobs-doing/$branch";
my $g_done_dir  = "/volume/dc-build01-d/QDIR/jobs-done/$branch";
my $g_workdir = '/d/smandal/QWORK';
system "mkdir -p $g_todo_dir $g_doing_dir $g_done_dir $g_workdir";

opendir D, $g_todo_dir or die;
my @jobs = map {chomp; $_}
           grep {(($_ ne '.') && ($_ ne '..'))}
           readdir D;
close D;

for my $job (sort byrev @jobs) {
    # TODO uncomment
    #process_job($job);    # also sets $sbsrc global variable
}

my $sbsrc = get_sbsrc();
#TODO remove this
$sbsrc = '/d/smandal/QWORK/DEV_FX_WASILA_12Q1_BRANCH/junos-1327470977/src';
do_build($sbsrc);


sub do_build
{
    my ($sbsrc) = @_;
    my ($sbparentdir, $sbname) = $sbsrc =~ m{^(.+)/([^/]+)/src/*$};
    if (!-d $sbparentdir) {
        die "Something wrong\n";
    }
    system "cd $sbparentdir && rm -f sb-junos && ln -s $sbname sb-junos";
    system "cd $sbparentdir && ~smandal/bin/build-qf.pl $branch HEAD HEAD";
}
{
my $firstjob;
my $sbsrc;
my @all_todo_elements;

sub process_job
#-----------------------------------------------------------------------
{
    if (!defined $firstjob) {
        $firstjob = 1;
        $sbsrc = '/tmp'; # so that no real damage can be done
        @all_todo_elements = ();
    }

    my ($job) = @_;

    my @elements = get_elements($job);
    if (intersects(\@all_todo_elements, \@elements)) {
        # Don't do this one
        return;
    }
    push @all_todo_elements, @elements;

    system "mv $g_todo_dir/$job $g_doing_dir/$job";
    print "$job\n";

    my $rev = $jobrev{$job};

    if ($firstjob) {
        $firstjob = 0;
        $sbsrc = mksb($branch, $rev);
        if (-d $sbsrc) {
            chdir $sbsrc;
            system "pwd";
        }
    }
    system "mkdir -p ../LOGS/$job";

    my $svninfo = get_svn_info('.');
    if ($rev == $svninfo->{'Last Changed Rev'}) {
        # No update needed
    }
    elsif ($rev > $svninfo->{'Last Changed Rev'}) {
        system "svn update --accept postpone -r $rev >../LOGS/$job/svnup.log 2>&1";
        # TODO check for conflicts
    }
    else {
        # $rev < $svninfo->{'Last Changed Rev'}
        # This should not happen
        print "\n\nSomething worng. rev: $rev < currentrev: " . $svninfo->{'Last Changed Rev'} . "\n";
        print "Aborting.\n\n";
        exit 3;
    }

    system "sh -x $g_doing_dir/$job/scripts/script.sh";
    for my $type ( qw(adds mods dels) ) {
        my $f = "$g_doing_dir/$job/scripts/${type}.txt";
        next if (!-f $f);
        open F, "<$f" or die;
        while (my $file = <F>) {
            chomp $file;
            if ($file =~ m{/Makefile\.depend\.}) {
                if (-e $file) {
                    unlink $file;
                    system "svn revert $file";
                }
            }
        }
        close F;
    }
}

sub get_sbsrc
{
    return $sbsrc;
}
}
sub intersects
#-----------------------------------------------------------------------
{
    my ($ar1, $ar2) = @_;

    for my $x (@$ar1) {
        for my $y (@$ar2) {
            my $qmx = quotemeta "$x/";
            my $qmy = quotemeta "$y/";
            if (($x =~ /^$qmy/) || ($y =~ /^$qmx/) || ($x eq $y)) {
                return 1;
            }
        }
    }
    return 0;
}
sub get_elements
#-----------------------------------------------------------------------
{
    my ($job) = @_;
    my @allelems = ();
    for my $type (qw(dels adds mods)) {
        my $file = "$g_todo_dir/$job/scripts/${type}.txt-deepest";
        if (-f $file) {
            open F, "<$file" or die;
            my @elems = map {chomp; $_} <F>;
            close F;
            push @allelems, @elems;
        }
    }
    return @allelems;
}
sub mksb
#-----------------------------------------------------------------------
{
    my ($branch, $rev) = @_;
    if ($TESTENV) {
        return mksb_test($branch, $rev);
    }
    else {
        return mksb_real($branch, $rev);
    }
}
sub mksb_real
#-----------------------------------------------------------------------
{
    my ($branch, $rev) = @_;
    my $time = time;
    my $sb_base = "junos-$time";
    system "mkdir -p $g_workdir/$branch";
    if ($branch eq 'trunk') {
        system "cd $g_workdir/$branch && mksb -n $sb_base SVN_REVISION=$rev";
    }
    else {
        system "cd $g_workdir/$branch && mksb -n $sb_base -r $branch SVN_REVISION=$rev";
    }

    return "$g_workdir/$branch/$sb_base/src";
}
sub mksb_test
#-----------------------------------------------------------------------
{
    my ($branch, $rev) = @_;
    my $s = 'file:///homes/smandal/bin/dir-qthis/ss';
    my $time = time;
    my $sb_base = "$branch-$time";
    if ($branch eq 'trunk') {
        system "cd $g_workdir && svn co $s/trunk\@$rev $sb_base";
    }
    else {
        system "cd $g_workdir && svn co $s/branches/$branch\@$rev $sb_base";
    }

    return "$g_workdir/$sb_base";
}
sub getrev
#-----------------------------------------------------------------------
{
    my $job = shift;
    open F, "<$g_todo_dir/$job/scripts/svninfo.txt" or die;
    my $branch_at_rev = <F>;
    close F;

    chomp $branch_at_rev;
    my ($b, $r) = $branch_at_rev =~ /^(.+)\@(.+)$/;
    if ($b ne $branch) {
        print "\n\nSomething is wrong. $job should be from branch $branch. But it is from $b.\n\n";
        exit 3;
    }
    return $r;
}
sub byrev
#-----------------------------------------------------------------------
{
    %jobrev = () unless (defined %jobrev);

    if (!exists $jobrev{$a}) {
        $jobrev{$a} = getrev($a);
    }
    if (!exists $jobrev{$b}) {
        $jobrev{$b} = getrev($b);
    }

    if ($jobrev{$a} != $jobrev{$b}) {
        return $jobrev{$a} <=> $jobrev{$b};
    }
    else {
        $a <=> $b;
    }
}
sub get_svn_info
#-----------------------------------------------------------------------
{
    my $what = shift;
    my @svn_info = `svn info $what`;
    if ($? != 0) {
        print "\n'svn info' failed. Are you sure you are in a subversion sandbox?\n\n";
        exit 2;
    }

    # 0  Path: .
    # 1  URL: https://om-scratch.googlecode.com/svn/trunk/src/sundry
    # 2  Repository Root: https://om-scratch.googlecode.com/svn
    # 3  Repository UUID: 40b42f04-cc1b-a860-77f9-d21a419cf73f
    # 4  Revision: 10
    # 5  Node Kind: directory
    # 6  Schedule: normal
    # 7  Last Changed Author: Om.Mandal@gmail.com
    # 8  Last Changed Rev: 10
    # 9  Last Changed Date: 2011-12-04 17:09:36 -0800 (Sun, 04 Dec 2011)
    my $svn_info = {};
    for my $line (@svn_info) {
        chomp $line;
        my ($key, $value) = $line =~ /^([^:]+)\s*:\s*(.*)$/;
        if ($key ne '') {
            $svn_info->{$key} = $value;
        }
    }
    my $root = $svn_info->{'Repository Root'};
    my $url  = $svn_info->{'URL'};
    my $qmroot = quotemeta $root;
    my ($rest) = $url =~ m/^$qmroot(.*)/;
    $rest =~ s{^/branches}{};
    $rest =~ s{^/}{};
    $rest =~ s{/.*}{};
    $svn_info->{'branch'} = $rest;
    return $svn_info;
}
